package com.gengine.core.frame
{
	import flash.events.*;
	import flash.utils.*;
	
	public class Frame extends Object implements IFrame
	{
		protected var delay:Number;
		
		private var _frameSortMap:Dictionary;
		private var _isPlay:Boolean;
		private var _oneFrameMap:Dictionary;
		private var _count:int;
		private var _frameCount:int = 0;
		private var _lastFrameCount:int = -1;
		private var _lastAry:Vector.<IBaseTimer>;
		private var _startTimer:int = 0;
		private var _prevTime:int = 0;
		private var _totalTime:int = 0;
		
		public function Frame(delay:Number)
		{
			this.delay = delay;
			this._frameSortMap = new Dictionary(true);
			this._isPlay = false;
			this._oneFrameMap = new Dictionary();	
		}
		
		public function dispatchEvent() : void
		{
		}
		
		public function play() : void
		{
			this._isPlay = true;
		}
		
		public function stop() : void
		{
			this._isPlay = false;
		}
		
		public function addTimer(baseTimer:IBaseTimer) : void
		{
			if (!this._isPlay)
			{
				play();
			}
			
			if (baseTimer.delay == 1)
			{
				_oneFrameMap[baseTimer.id] = baseTimer;
			}
			else
			{
				pushFrameSort(baseTimer);
			}
			
			_count += 1;
		}
		
		public function pushFrameSort(baseTimer:IBaseTimer) : void
		{
			var lastFrameCount:int = this._frameCount + baseTimer.delay;
			var lastAry:Vector.<IBaseTimer> = null;
			if (this._lastFrameCount == lastFrameCount)
			{
				lastAry = this._lastAry; 
			}
			else
			{
				lastAry = _frameSortMap[lastFrameCount] as Vector.<IBaseTimer>;
			}
			
			if (lastAry)
			{
				lastAry[lastAry.length] = baseTimer;
			}
			else
			{
				lastAry = new Vector.<IBaseTimer>(0, false);
				lastAry[0] = baseTimer;
				this._frameSortMap[lastFrameCount] = lastAry;
			}
			
			this._lastFrameCount = lastFrameCount;
			this._lastAry = lastAry;
		}
		
		protected function onEnterFrameHandler(event:Event = null) : void
		{
			var interval:int = 0;
			var now:* = getTimer();
			if (this._prevTime == 0)
			{
				interval = 0;
			}
			else
			{
				interval = now - this._prevTime;
				this.renderer(interval);
			}
			this._prevTime = now;
		}
		
		protected function renderer(interval:int) : void
		{
			_frameCount = _frameCount + 1;
			var baseTimer:* = this._frameSortMap[this._frameCount] as Vector.<IBaseTimer>;
			var timer:* = getTimer();
			this.EnterFrameFor(baseTimer, interval);
		}
		
		private function EnterFrameFor(baseTimer:Vector.<IBaseTimer>, interval:int) : void
		{
			var timer:IBaseTimer = null;
			for each (timer in this._oneFrameMap)
			{
				
				if (timer.isDelete)
				{
					_count = _count - 1;
					delete this._oneFrameMap[timer.id];
					continue;
				}
				if (timer.running)
				{
					timer.interval = interval;
					timer.renderer(this._frameCount);
				}
			}
			if (baseTimer)
			{
				for each (timer in baseTimer)
				{
					
					if (timer.isDelete)
					{
						_count = _count - 1;
						timer.dispose();
						continue;
					}
					if (timer.running)
					{
						timer.interval = interval;
						timer.renderer(this._frameCount);
					}
					this.pushFrameSort(timer);
				}
				baseTimer.length = 0;
				delete this._frameSortMap[this._frameCount];
			}
		}
	}
}